/*
 * Copyright (c) 2017, Li Bo/Alex Lee All rights reserved.
 * 
 * http://www.libo4dream.club/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package com.hyts.socketio.base;

import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.DataListener;
import com.hyts.socketio.config.BaseServerConfig;
import com.hyts.socketio.listener.SocketExceptionListener;
import com.hyts.socketio.tool.StringUtils;

/**
 * @ClassName: BaseSocketIOServer
 * @Description: 基础SocketIO-Server服务
 * @author: LiBo/Alex Lee
 * @date: 2017年10月6日 下午10:15:43
 * @email: alexlibochn@china-pui.com.cn/alex.link@foxmail.com
 */
public abstract class BaseSocketIOServer<T> {
	
	/**
	 * @fieldName: configuration
	 * @fieldType: Configuration
	 * @Description: 配置
	 */
	private Configuration configuration;
	
	/**
	 * @fieldName: socketServer
	 * @fieldType: SocketIOServer
	 * @Description: socketIOServer服务
	 */
	private SocketIOServer socketServer;
	
	
	/**  
	 * 创建一个新的实例-构造器 BaseSocketIOServer.  
	 * @param model
	 * @param isExtConfiguration  
	 */ 
	public BaseSocketIOServer(BaseSocketIOModel model,boolean isExtConfiguration,BaseExtTransferIOModel extModel)
	{
		//构建配置
		if(isExtConfiguration)
			this.buildExtConfiguration(model);
		else
			this.buildConfiguration(model);
		//构建服务
		this.buildSocketServer();
		//构建基础监听Socket服务监听器
		if(extModel != null && extModel.listenerClass != null)
			this.buildExtSocketListener(extModel.listenerName, extModel.modelClass, (DataListener) extModel.listenerClass);
		else
			this.buildBaseSocketListener();
	}
	
	
	/**
	 * @Title: preBaseConfiguration
	 * @Description: 构建初始化Configuration对象操作类
	 * @param model
	 * @return
	 * @return: Configuration
	 */
	private BaseSocketIOServer buildConfiguration(BaseSocketIOModel model)
	{
		if(model == null)
		{
			throw new NullPointerException("传入的BaseSocketIOModel对象不可以为空!");
		}
		configuration = new Configuration();
		configuration.setAddVersionHeader(BaseServerConfig.DEFAULT_SHOW_VERSION_ADD_FLAG);
		configuration.setExceptionListener(new SocketExceptionListener());
		configuration.setContext(StringUtils.defaultValue(model.contextPath, BaseServerConfig.DEFAULT_CONTEXT_PATH));
		configuration.setBossThreads(model.bbossThreadNum == null?BaseServerConfig.DEFAULT_BOSS_THREAD_NUM:model.bbossThreadNum);
		configuration.setWorkerThreads(model.workThreadNum == null?BaseServerConfig.DEFAULT_WORK_THREAD_NUM:model.workThreadNum);
		configuration.setHostname(StringUtils.defaultValue(model.hostName, BaseServerConfig.DEFAULT_HOST_NAME));
		configuration.setPort(Integer.parseInt(StringUtils.defaultValue(model.port,BaseServerConfig.DEFAULT_PORT_VALUE.toString())));
		return this;
	}

	/**
	 * @Title: buildExtConfiguration
	 * @Description: 构建扩展配置服务操作
	 * @return
	 * @return: BaseSocketIOServer
	 */
	public abstract <T> BaseSocketIOServer buildExtConfiguration(T extModel);
	
	/**
	 * @Title: buildSocketServer
	 * @Description: 构建服务信息操作
	 * @return
	 * @return: BaseSocketIOServer
	 */
	private BaseSocketIOServer buildSocketServer()
	{
		if(socketServer != null && this.configuration != null)
			socketServer = new SocketIOServer(configuration);
		return this;
	}
	
	/**
	 * @Title: buildBaseSocketListener
	 * @Description: 构建基础构建socketIO监听器
	 * @return
	 * @return: BaseSocketIOServer
	 */
	private BaseSocketIOServer buildBaseSocketListener()
	{
		if(socketServer != null && this.configuration != null)
			socketServer.addEventListener(BaseServerConfig.DEFAULT_EVENT_LISTENER_NAME, BaseSocketIOModel.class, new BaseSocketIOListener(this.socketServer));
		return this;
	}
	
	/**
	 * @Title: buildExtSocketListener
	 * @Description: 构建扩展配置服务操作
	 * @return
	 * @return: BaseSocketIOServer
	 */
	public abstract BaseSocketIOServer buildExtSocketListener(String listenerName,Class<? extends BaseExtTransferIOModel> clazz,DataListener listener);
	
	/**
	 * @Title: go
	 * @Description: 继续
	 * @return: void
	 */
	public boolean go()
	{
		socketServer.start();
        try {
			Thread.sleep(Integer.MAX_VALUE);
		} catch (InterruptedException e) {
			e.printStackTrace();
			return false;
		}
        socketServer.stop();	
        return true;
	}  
}
